<?php

declare(strict_types=1);

namespace app\api\controller;

use app\api\lib\SuPengJun;
use app\api\lib\Wechat;
use app\api\service\GoodsService;
use app\api\service\OrderService;
use app\common\model\activity\ActivityModel;
use app\common\model\activity\ActivityProductModel;
use app\common\model\goods\GoodsCardModel;
use app\common\model\goods\GoodsModel;
use app\common\model\goods\GoodsProductModel;
use app\common\model\order\OrderGoodsModel;
use app\common\model\order\OrderModel;
use app\common\model\order\OrderRefundModel;
use app\common\model\user\UserActivityModel;
use app\common\model\user\UserAddressModel;
use app\common\model\user\UserCardModel;
use app\common\model\user\UserCartModel;
use app\common\model\user\UserModel;
use app\common\service\ConfigService;
use think\Request;

class Order extends Controller
{

    /**
     * 获取待生成订单商品信息
     * @param array $type 类型:0=购物车商品,1=立即支付商品
     * @param array $pid 规格ID，type=1时必填
     * @return json|array
     * @throws \AlibabaCloud|Client|Result|array
     */
    public function goods_settlement(Request $request)
    {

        $uid = $request->uid;
        $type = $request->get('type', 0);
        $pid = $request->get('pid', 0);
        $quantity = $request->get('quantity', 0);
        if ($type == 1) {
            $item = ['id' => $uid, 'goods_product_id' => $pid, 'quantity' => $quantity];
            $item['product'] = GoodsProductModel::where('id', $pid)->field('goods_id,price,line_price,img,name')->find();
            if (!$item['product']) return error('生成订单异常，请稍后重试！');
            $item['goods_id'] = $item['product']['goods_id'];
            $item['goods_name'] = GoodsModel::where('id', $item['product']['goods_id'])->value('name');
            if (!$item['goods_name']) return error('生成订单异常，请稍后重试！');
            $data[] = $item;
        } else {
            $data = UserCartModel::where('user_id', $uid)->where('check', 1)->where('status', 1)
                ->order(['status' => 'asc', 'id' => 'desc'])
                ->field('id,goods_id,goods_product_id,quantity')
                ->select();
            if (!$data) return error('生成订单异常，请稍后重试！');
            $data->map(function ($v) {
                $v['product'] = GoodsProductModel::where('id', $v['goods_product_id'])->field('price,line_price,img,name')->find();
                $v['goods_name'] = GoodsModel::where('id', $v['goods_id'])->value('name');
                return $v;
            });
        }
        return success('success', $data);
    }

    /**
     * 支付
     * @param array $type 类型:0=购物车商品,1=立即支付商品
     * @param array $aid 地址ID
     * @param array $pid 规格ID
     * @param array $cid 卡卷ID
     * @param array $remark 备注
     * @return json|array
     * @throws \AlibabaCloud|Client|Result|array
     */
    public function settlement_pay(Request $request)
    {
        $uid = $request->uid;
        $type = $request->post('type', 0);
        $pid = $request->post('pid', 0);
        $quantity = $request->post('quantity', 0);
        $aid = $request->post('aid', 0);
        $cid = $request->post('cid', 0);
        $remark = $request->post('remark', '');
        $addressInfo = UserAddressModel::where('id', $aid)->field('name,mobile,province,city,county,detailed')->find();
        if (!$addressInfo) return error('收货地址异常，请稍后重试！');
        $openid = UserModel::where('id', $uid)->value('wx_openid');
        if (!$openid) return error('账号数据异常，请稍后重试！');
        $out_trade_no = SuPengJun::getSn(1);
        if ($type == 1) {
            $item = ['goods_product_id' => $pid, 'quantity' => $quantity];
            $item['product'] = GoodsProductModel::where('id', $pid)->field('goods_id,price,line_price,img,name')->find();
            if (!$item['product']) return error('商品数据异常，请稍后重试！');
            $item['goods_id'] = $item['product']['goods_id'];
            $item['goods_name'] = GoodsModel::where('id', $item['product']['goods_id'])->value('name');
            if (!$item['goods_name']) return error('商品数据异常，请稍后重试！');
            $orderGoods[] = $item;
            $goods_count = $quantity;
            $goods_amount = $item['product']['line_price'];
            $discount_amount = round($item['product']['line_price'] - $item['product']['price'], 2);
            $total_fee = round($item['product']['price'] * $quantity, 2);
        } else {
            $orderGoods = UserCartModel::where('user_id', $uid)->where('check', 1)->where('status', 1)
                ->order(['status' => 'asc', 'id' => 'desc'])
                ->field('goods_id,goods_product_id,quantity')
                ->select();
            if (!$orderGoods) return error('商品数据异常，请稍后重试！');
            $orderGoods->map(function ($v) {
                $v['product'] = GoodsProductModel::where('id', $v['goods_product_id'])->field('price,line_price,img,name')->find();
                if (!$v['product']) return error('商品数据异常，请稍后重试！');
                $v['goods_name'] = GoodsModel::where('id', $v['goods_id'])->value('name');
                if (!$v['goods_name']) return error('商品数据异常，请稍后重试！');
                return $v;
            });
            $goods_count = 0;
            $goods_amount = 0;
            $discount_amount = 0;
            $total_fee = 0;
            foreach ($orderGoods as $v) {
                $goods_count += $v['quantity'];
                $goods_amount += $v['product']['line_price'];
                $discount_amount += $v['product']['line_price'] - $v['product']['price'];
                $total_fee += $v['product']['price'] * $v['quantity'];
            }
            $goods_amount = round($goods_amount, 2);
            $discount_amount = round($discount_amount, 2);
            $total_fee = round($total_fee, 2);
            UserCartModel::where('user_id', $uid)->where('check', 1)->where('status', 1)->delete();
        }
        if ($cid) {
            $cardId = UserCardModel::where('id', $cid)->value('card_id');
            UserCardModel::where('id', $cid)->update(['status' => 2, 'use_time' => time()]);
            $card_price = GoodsCardModel::where('id', $cardId)->value('price');
            $total_fee = round($total_fee - $card_price, 2);
        }
        $orderId = (new OrderModel())->insertGetId([
            'order_no' => $out_trade_no,
            'goods_count' => $goods_count,
            'goods_amount' => $goods_amount,
            'discount_amount' => $discount_amount,
            'order_amount' => $total_fee,
            'user_card_id' => $cid ? $cid : 0,
            'card_price' => $cid ? $card_price : 0,
            'user_name' => $addressInfo['name'],
            'user_mobile' => $addressInfo['mobile'],
            'user_adds' => $addressInfo['province'] . $addressInfo['city'] . $addressInfo['county'] . $addressInfo['detailed'],
            'remark' => $remark,
            'user_id' => $uid,
            'pay_status' => 0,
            'status' => 1,
            'create_time' => time(),
        ]);
        if (!$orderId) return error('商品数据异常，请稍后重试！');
        $ogModel = [];
        foreach ($orderGoods as $k => $v) {
            $ogModel[$k]['order_id'] = $orderId;
            $ogModel[$k]['goods_id'] = $v['goods_id'];
            $ogModel[$k]['goods_product_id'] = $v['goods_product_id'];
            $ogModel[$k]['goods_name'] = $v['goods_name'];
            $ogModel[$k]['product_price'] = $v['product']['price'];
            $ogModel[$k]['product_line_price'] = $v['product']['line_price'];
            $ogModel[$k]['product_img'] = $v['product']['img'];
            $ogModel[$k]['product_name'] = $v['product']['name'];
            $ogModel[$k]['quantity'] = $v['quantity'];
        }
        (new OrderGoodsModel)->insertAll($ogModel);
        $data = (new Wechat())->pay($openid, $total_fee, $out_trade_no, $out_trade_no);
        if (!$data) return error('支付异常，请稍后重试！');
        return success('success', $data);
    }

    /**
     * 活动商品支付
     * @param array $param 参数类型参数名参数作用
     * @return json|array
     * @throws \AlibabaCloud|Client|Result|array
     */
    public function activity_pay(Request $request)
    {
        $uid = $request->uid;
        $activityId = $request->post('activity_id', 0);
        $activityProductId = $request->post('activity_product_id', 0);
        $quantity = $request->post('quantity', 1);
        $user = UserModel::where('id', $uid)->field('avatar,wx_openid')->find();
        if (!$user) return error('账号数据异常，请稍后重试！');
        $activity = ActivityModel::where('id', $activityId)->field('name,imgs')->find();
        $activityProduct = ActivityProductModel::where('id', $activityProductId)
            ->field('name,price,line_price,stock')->find();
        if (!$activity || !$activityProduct) return error('活动数据异常，请稍后重试！');
        $out_trade_no = SuPengJun::getSn(6);
        $goods_count = $quantity;
        $goods_amount = round($activityProduct['line_price'] * $quantity, 2);
        $total_fee = round($activityProduct['price'] * $quantity, 2);
        $discount_amount = round($goods_amount - $total_fee, 2);
        $orderId = (new OrderModel())->insertGetId([
            'order_no' => $out_trade_no,
            'goods_count' => $goods_count,
            'goods_amount' => $goods_amount,
            'discount_amount' => $discount_amount,
            'order_amount' => $total_fee,
            'user_name' => '无',
            'user_mobile' => '无',
            'user_adds' => '无',
            'user_id' => $uid,
            'pay_status' => 0,
            'status' => 1,
            'type' => 1,
            'create_time' => time(),
        ]);
        if (!$orderId) return error('创建订单失败，请稍后重试！');
        $codeList = [];
        for ($i = 0; $i < $quantity; $i++) {
            do {
                $code = SuPengJun::generateRandomCode();
                $exists = UserActivityModel::where('code', 'like', '%' . $code . '%')->value('id');
            } while ($exists);
            $codeList[] = $code;
        }
        $userAddressId = (new UserActivityModel())->insertGetId([
            'order_id' => $orderId,
            'user_id' => $uid,
            'user_avatar' => $user['avatar'],
            'activity_id' => $activityId,
            'activity_name' => $activity['name'],
            'activity_img' => explode(',', $activity['imgs'])[0],
            'activity_product_id' => $activityProductId,
            'activity_product_name' => $activityProduct['name'],
            'quantity' => $quantity,
            'code' => implode(',', $codeList),
            'status' => 9,
            'create_time' => time(),
        ]);
        if (!$userAddressId) return error('创建订单失败，请稍后重试！');
        $data = (new Wechat())->pay($user['wx_openid'], $total_fee, $out_trade_no, $out_trade_no);
        if (!$data) return error('支付异常，请稍后重试！');
        return success('success', $data);
    }

    /**
     * 订单列表
     * @param array $id 0=全部,
     * 1=支付状态为未付款，订单状态为待付款,
     * 2=支付状态为未付款、已付款、售后中、部分退款，订单状态为待发货，
     * 3=支付状态为未付款、已付款、售后中、部分退款，订单状态为已发货，
     * 4=支付状态为未付款、已付款、售后中、部分退款，订单状态为已收货,
     * 5=支付状态为售后中、部分退款、全部退款，订单状态不等于已取消
     */
    public function list(Request $request)
    {
        $uid = $request->uid;
        $type = $request->get('type', 0);
        $condition[] = ['type', '=', 0];
        $condition[] = ['user_id', '=', $uid];
        $condition[] = ['status', '<>', 6];
        if ($type == 1) {
            $condition[] = ['pay_status', '=', 0];
            $condition[] = ['status', '=', 1];
        } else if ($type == 2) {
            $condition[] = ['pay_status', 'in', [0, 1, 2, 3]];
            $condition[] = ['status', '=', 2];
        } else if ($type == 3) {
            $condition[] = ['pay_status', 'in', [0, 1, 2, 3]];
            $condition[] = ['status', '=', 3];
        } else if ($type == 4) {
            $condition[] = ['pay_status', 'in', [0, 1, 2, 3]];
            $condition[] = ['status', '=', 4];
        } else if ($type == 5) {
            $condition[] = ['pay_status', 'in', [2, 3, 4]];
            $condition[] = ['status', '<>', 0];
        }
        if (OrderService::handle_order($uid)) {
            $data = OrderModel::where($condition)->order('id', 'desc')
                ->field(OrderService::order_find())
                ->paginate(12);
            $data->map(function ($v) {
                $v['goods'] = OrderGoodsModel::where('order_id', $v['id'])->column('product_img');
                $v['status_str'] = OrderService::status_str($v['pay_status'], $v['status']);
                $v['ship_time_str'] = date('Y-m-d H:i:s', $v['ship_time']);
                $v['confirm_time_str'] = date('Y-m-d H:i:s', $v['ship_time']);
                return $v;
            });
            return success('success', $data);
        }
    }

    /**
     * 订单详情
     * @param array $id 订单ID
     * @return json|array
     * @throws \AlibabaCloud|Client|Result|array
     */
    public function details(Request $request)
    {
        $id = $request->get('id');
        $data = OrderModel::where('id', $id)->field(OrderService::order_find(1))->find();
        if (!$data) return error('未找到订单，请稍后重试！');
        $fd = 'id,goods_id,goods_name,product_price,product_line_price,product_img,product_name,quantity,status';
        $data['goods'] = OrderGoodsModel::where('order_id', $id)->field($fd)->select();
        $data['status_str'] = OrderService::status_str($data['pay_status'], $data['status']);
        if ($data['ship_time']) $data['ship_time_str'] = date('Y-m-d H:i:s', $data['ship_time']);
        if ($data['confirm_time']) $data['confirm_time_str'] = date('Y-m-d H:i:s', $data['confirm_time']);
        $refund = ConfigService::get('type', 'shop_adds');
        $data['refund'] = $refund ? explode(',', $refund) : ['', '', ''];
        return success('success', $data);
    }

    public function payment(Request $request)
    {
        $uid = $request->uid;
        $id = $request->post('id', 0);
        $orderInfo = OrderModel::where('id', $id)->field(['order_no', 'order_amount'])->find();
        if (!$orderInfo) return error('订单异常，请稍后重试！');
        $openid = UserModel::where('id', $uid)->value('wx_openid');
        if (!$openid) return error('账号数据异常，请稍后重试！');
        $data = (new Wechat())->pay($openid, $orderInfo['order_amount'], $orderInfo['order_no'], $orderInfo['order_no']);
        if ($data) {
            return success('success', $data);
        } else {
            return error('支付异常，请稍后重试！');
        }
    }

    /**
     * 删除订单
     * @param array $id 订单ID
     * @param array $type 类型:0=删除订单,1=取消订单,2=已收货,3=催付订单
     * @param array $refund 是否退款:0=否,1=是
     * @return json|array
     * @throws \AlibabaCloud|Client|Result|array
     */
    public function edit(Request $request)
    {
        $uid = $request->uid;
        $id = $request->post('id', 0);
        $type = $request->post('type', 0);
        $refund = $request->post('refund', 0);
        $model = [];
        if ($type == 3) {
            event('OrderUrgeDelivery', ['oid' => $id]);
        } else {
            if ($refund) {
                $orderInfo = OrderModel::where('id', $id)->where('user_id', $uid)->field('serial_number,order_no,payed,can_refund_price')->find();
                if (!$orderInfo) return error('订单异常，请稍后重试！');
                if ($orderInfo['serial_number'] && $orderInfo['order_no'] && $orderInfo['payed'] && $orderInfo['can_refund_price']) {
                    $out_refund_no = SuPengJun::getSn(4);
                    (new OrderRefundModel())->insert([
                        'refund_no' => $out_refund_no,
                        'refund_reason' => '未发货用户主动取消订单',
                        'refund_price' => $orderInfo['can_refund_price'],
                        'order_id' => $id,
                        'create_time' => time(),
                    ]);
                    (new Wechat())->refund($orderInfo['serial_number'], $out_refund_no, $orderInfo['payed'], $orderInfo['can_refund_price']);
                    $model = ['pay_status' => 2];
                    OrderService::return_card($id);
                    event('OrderAfterSale', ['oid' => $id]);
                }
            } else {
                if ($type == 0) {
                    $model = ['status' => 6];
                } else if ($type == 1) {
                    $model = ['status' => 0];
                    OrderService::return_card($id);
                } else if ($type == 2) {
                    $model = ['status' => 4];
                }
            }
            OrderModel::where('id', $id)->where('user_id', $uid)->update($model);
        }
        return success('操作成功！');
    }

    /**
     * 申请退款
     * @param array $id 订单ID
     * @param array $type 物流类型：0 未收到货、1已收到货
     * @param array $express 退款物流名称
     * @param array $express_no 退款物流单号
     * @param array $reason 退款原因
     * @return json|array
     * @throws \AlibabaCloud|Client|Result|array
     */
    public function refund(Request $request)
    {
        $uid = $request->uid;
        $id = $request->post('id', 0);
        $type = $request->post('type', 0);
        $express = $request->post('express', '');
        $express_no = $request->post('express_no', '');
        $reason = $request->post('reason', '');
        $out_refund_no = SuPengJun::getSn(4);
        (new OrderRefundModel())->insert([
            'refund_no' => $out_refund_no,
            'refund_type' => $type,
            'refund_express' => $express,
            'refund_express_no' => $express_no,
            'refund_reason' => $reason,
            'order_id' => $id,
            'create_time' => time(),
        ]);
        OrderModel::where('id', $id)->where('user_id', $uid)->update(['pay_status' => 2]);
        event('OrderRefund', ['oid' => $id]);
        return success('操作成功！');
    }

    /**
     * 可用优惠卷
     */
    public function use_card(Request $request)
    {
        $uid = $request->uid;
        $productId = $request->post('product_id', 0);
        $amount = $request->post('amount', 0);
        UserCardModel::where('expire_time', '<=', time())->update(['status' => 3]);
        $goodsIds = [];
        $classifyIds = [];
        if ($productId == 0) {
            if (GoodsService::handle_cart($uid)) {
                $goodsIds = UserCartModel::where('user_id', $uid)->where('check', 1)->column('goods_id');
                if (!empty($goodsIds)) {
                    $classifyIds = GoodsModel::whereIn('id', $goodsIds)->whereNotNull('classify_ids')->column('classify_ids');
                    if (!empty($classifyIds)) {
                        $allIds = [];
                        foreach ($classifyIds as $str) {
                            $ids = explode(',', $str);
                            $allIds = array_merge($allIds, $ids);
                        }
                        $classifyIds = array_values(array_map('intval', array_unique($allIds)));
                    }
                }
            }
        } else {
            $goodsId = GoodsProductModel::where('id', $productId)->value('goods_id');
            $goodsIds = [$goodsId];
            $classifyIds = GoodsModel::where('id', $goodsId)->value('classify_ids');
            $classifyIds =  is_array($classifyIds) ? implode(',', $classifyIds) : [];
        }
        $data = UserCardModel::where('status', 1)->where('user_id', $uid)
            ->field('id,card_id')->select();
        $data->map(function ($v) use ($goodsIds, $classifyIds, $amount) {
            $v['card'] = GoodsCardModel::where('id', $v['card_id'])->find();
            $v['available'] = false;
            if ($v['card']['limit'] == 1 && $v['card']['limit_price'] <= $amount) {
                $v['available'] = true;
            } else if ($v['card']['limit'] == 2) {
                $v['available'] = in_array($v['card']['limit_id'], $goodsIds, true);
            } else if ($v['card']['limit'] == 3) {
                $v['available'] = in_array($v['card']['limit_id'], $classifyIds, true);
            }
            $v['card']['neck_create_time'] = date('Y/m/d', strtotime($v['card']['create_time']));
            $v['card']['expire_time'] = date('Y/m/d', $v['card']['expire_time']);
            return $v;
        });
        $availableItems = $data->filter(function ($item) {
            return $item['available'] === true;
        });
        $availableCount = $availableItems->count();
        $maxPriceItem = $availableItems->sort(function ($a, $b) {
            return $b['card']['price'] <=> $a['card']['price'];
        })->first();
        return success('success', [$maxPriceItem, $availableCount, $data]);
    }
}
